package com.qidian.buy.search.dao.impl;

import com.qidian.buy.search.dao.SearchItemDAO;
import com.qidian.buy.search.pojo.SearchItem;
import com.qidian.buy.util.Tools;
import com.qidian.buy.util.pojo.QdResult;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Author: 戴着假发的程序员
 * Date: 2024-05-13 12:00
 * company: 起点编程
 **/
@Repository // 和 @Component 一样  表示持久化操作的bean
public class SearchItemDAOImpl implements SearchItemDAO {
    @Autowired
    private RestHighLevelClient client;// 注入ES的高级客户端
    @Value("${INDEX_NAME}")
    private String indexName;
    @Override
    public int saveSearchItem(SearchItem item) {
        // 创建request
        IndexRequest request = new IndexRequest(indexName);
        // 设置索引的id为商品的id
        request.id(item.getItemId().toString());
        // 设置数据
        request.source(Tools.object2json(item), XContentType.JSON);
        // 提交数据
        try {
            IndexResponse response = client.index(request, RequestOptions.DEFAULT);
            if (response.getResult().getLowercase().equalsIgnoreCase("CREATED")){
                return 1;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return 0;
    }

    @Override
    public List<SearchItem> selectByPage(int page, int limit, String kw) {
        SearchRequest request = new SearchRequest(indexName);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        if (kw != null && !kw.equals(""))
            builder.query(QueryBuilders.fuzzyQuery("itemTitle",kw).fuzziness(Fuzziness.ONE));
        // 分页设置
        builder.from((page - 1) * limit);
        builder.size(limit);
        // 高亮显示设置
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("itemTitle");
        highlightBuilder.preTags("<font color='red'>");
        highlightBuilder.postTags("</font>");
        builder.highlighter(highlightBuilder);

        request.source(builder);
        // 查询
        try {
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            Iterator<SearchHit> iterator = response.getHits().iterator();
            List<SearchItem> items = new ArrayList<>();
            while (iterator.hasNext()){
                SearchHit hit = iterator.next();
                Map<String, Object> map = hit.getSourceAsMap();
                SearchItem item = Tools.json2object(Tools.object2json(map), SearchItem.class);
                // 获取高亮显示的结果
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                HighlightField itemTitle = highlightFields.get("itemTitle");
                if(itemTitle != null ) {
                    Text[] fragments = itemTitle.getFragments();
                    if (fragments != null && fragments.length > 0) {
                        item.setItemTitle(fragments[0].string());
                    }
                }
                items.add(item);
            }
            return items;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public int selectCount(String kw) {
        SearchRequest request = new SearchRequest(indexName);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        if (kw != null && !kw.equals(""))
            builder.query(QueryBuilders.fuzzyQuery("itemTitle",kw).fuzziness(Fuzziness.ONE));
        request.source(builder);
        try {
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            return (int) response.getHits().getTotalHits().value;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
